package nl.boelen.game.client.connection;

import java.net.InetAddress;
import nl.boelen.game.client.Client;
import nl.boelen.game.entities.PlayerMP;
import nl.boelen.game.net.packet.Packet;
import nl.boelen.game.net.packet.Packet10Join;
import nl.boelen.game.net.packet.Packet11Leave;
import nl.boelen.game.net.packet.Packet12Request;
import nl.boelen.game.net.packet.Packet14CheckConnection;
import nl.boelen.game.net.packet.Packet20Chunk;
import nl.boelen.game.net.packet.Packet30Health;
import nl.boelen.game.net.packet.Packet31Movement;
import nl.boelen.game.net.packet.PacketTypes;
import nl.boelen.game.utils.Utils;

public class ClientPacketHandler {
    private Client client;
    private ClientTCPSender TCP;

    public ClientPacketHandler(Client client, ClientTCPSender TCP) {
        this.client = client;
        this.TCP = TCP;
    }

    public void parsePacket(byte[] data, InetAddress address, int port) {
        String message = new String(data).trim();
        PacketTypes type = Packet.lookupPacket(message.substring(0, 2));
        switch (type) {
            default:
            case INVALID:
                break;
            case JOIN: // TCP
                handleLogin(new Packet10Join(data), address, port);
                break;
            case LEAVE: // TCP
                // Make this a LEAVE packet
                handleDisconnect(new Packet11Leave(data));
                break;
            case MOVEMENT: // UDP
                handleMove(new Packet31Movement(data));
                break;
            case CLOSEDSERVER: // TCP
                handleClosedServer();
                break;
            case CHECKCONNECTION: // TCP
                handleCheck(new Packet14CheckConnection(client.player.getUniqueKey()));
                break;
            case CHUNK: // UDP
                handleChunk(new Packet20Chunk(data));
                break;
            case HEALTH:
                handleHealth(new Packet30Health(data));
                break;
        }
    }

    private void handleLogin(Packet10Join p, InetAddress address, int port) {
        addPlayerToGame(p, address, port);
    }

    private void handleDisconnect(Packet11Leave p) {
        Utils.LOG(p.getUsername() + " has left the world");
        client.level.removePlayerMP(p.getUniqueKey());
    }

    private void handleMove(Packet31Movement p) {
        PlayerMP playerToMove = client.level.getPlayerMP(p.getUniqueKey());
        if (playerToMove != null) {
            playerToMove.handleMovement(p);
        } else {
            Packet12Request getPacket = new Packet12Request(client.player.getUniqueKey(), p.getUniqueKey());
            TCP.sendPacket(getPacket);
        }
    }

    private void handleClosedServer() {
        Utils.LOG("Server stopped hosting");
        client.level.closedServer(client.player);
        client.serverOnline = false;
    }

    private void handleCheck(Packet14CheckConnection p) {
        TCP.sendPacket(p);
    }

    private void handleChunk(Packet20Chunk p) {
        Utils.LOG("got a chunk from the server");
    }

    private void handleHealth(Packet30Health p) {
        PlayerMP player = client.level.getPlayerMP(p.getUniqueKey());
        if (player != null) {
            player.getHealthObject().setHp(p.getHp());
        }
    }

    public void addPlayerToGame(Packet10Join p, InetAddress address, int port) {

        boolean playerExists = client.level.doesPlayerMPExists(p.getUniqueKey());
        if (!playerExists) {

            Utils.LOG(p.getUsername() + " has joined the game");
            PlayerMP player = new PlayerMP(client, p.getX(), p.getY(), p.getUsername(), address, port,
                    p.getUniqueKey(), p.getShirtColor(), p.getMovingDirection(), p.getMaxhp());
            player.getHealthObject().setHp(p.getHp());
            client.level.addEntity(player);
        }
    }
}
